package model.objects;

import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;

import model.general.Location;
import model.move.IMove;
import model.move.MoveHook;
import model.observer.Obsever;
import model.observer.Obseverable;
import model.option.Option;

public class Hook extends Sprites implements IAnimateSubActor{
	private List<IAnimateItems> list = new ArrayList<IAnimateItems>();
	private IAnimateMainActor boat;
	private IAnimateItems itemCatched = null;
	private IMove move;
	private Thread thread;
	
	private boolean isCatchOther = false;
	private boolean isStayBoat = true;
	private boolean isThrowed = false;
	private boolean isPull = false;
	
	public Hook(int x, int y, String srcImg, IAnimateMainActor boat) {
		super(x, y, srcImg);
		this.boat = boat;
		this.move = new MoveHook(location);
	}

	@Override
	public void move() {
		//di chuyen ne ^^
		//uoc gi no tu hieu :D gio minh coi thu cai hook cu lam lam sao nha^^
		while (isThrowed) {
			hasOutBottom();
			if (isCatchOther || isPull) {
				moveUp();
			} else {
				moveDown();
			}
			
			try {
				Thread.sleep(10);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public void hasOutBottom(){
		if (location.getY() > 600) {
			isPull = true;
		}
	}
	
	/**
	 * Hook move up to come back Boat. 1. if in the Boat, it's not move 2. if
	 * not int the Boat, it's move up until arrived Boat is stop here.
	 * 
	 * @param
	 * @return void
	 */
	public void moveUp() {
		if (!isArrivedBoat()) {
			System.out.println("Hook is drawing up come back boat");
			move.moveUp();
			if (!isCatchOther) {
				notifyObsever();
			} else {
				itemCatched.updateLocation(location);
			}
		} else {
			System.out.println("I'm Hook. I'm stay in the Boat now");
			//neu toi thuyen roi thi xu ly
			//1. co ca --> addoption 
			if (isCatchOther) {
				itemCatched.destroyed();
				isCatchOther = false;
				itemCatched = null;
			}
			//2. neu ko thi reset lai mac dinh
			reset();
		}
	}
	
	public void reset(){
		isCatchOther = false;
		itemCatched = null;
		isThrowed = false;
		isPull = false;
		updateLocation(boat.getLocation());
	}
	
	/**
	 * Check the Hook has been arrived the Boat ?!?
	 * @param
	 * @return boolean
	 */ 
	public boolean isArrivedBoat() {
		if (identifyLocationHook(boat.getLocation()).getY() >= location.getY()) {
			isStayBoat = true;
		} else {
			isStayBoat = false;
		}
		return isStayBoat;
	}
	
	public Location identifyLocationHook(Location locBoat){
		int x = (locBoat.getX() + (boat.getWidth() / 2)) - this.width;
		int y = (locBoat.getY() + (boat.getHeight() / 2));
		return new Location(x, y);
	}
	
	/**
	 * Hook move down to catch fish or items.
	 * 
	 * @param
	 * @return void
	 */
	//dau tien la coi moveDown nha
	public void moveDown() {
		System.out.println("Hook is throwing to catch fish");
		move.moveDown();
		isStayBoat = false;
		//neu chua bat duoc gi thi notify
		if (!isCatchOther) {
			notifyObsever();
		} else {
			//con neu bat duoc thi cho fish di chuyen theo
			itemCatched.updateLocation(location);
		}

	}
	
	@Override
	public void show(Graphics g) {
		int x = boat.getLocation().getX() + (boat.getWidth()/2) - (width/2);
		int y = boat.getLocation().getY() + (boat.getHeight()/2);
		//ve day cau
		g.fillRect(x, y, 2, location.getY() - y);
		//ve luoi cau (hook)
		g.drawImage(img, location.getX(), location.getY(), null);
	}

	@Override
	public void updateLocation(Location loc) {
		this.location.setX(loc.getX() + boat.getWidth()/3);
	}
	
	@Override
	public Location getLocation() {
		return location;
	}

	@Override
	public void addObsever(IAnimateItems obsever) {
		list.add(obsever);
	}

	@Override
	public void notifyObsever() {
		for (int i = 0; i < list.size(); i++) {
			list.get(i).check();
		}
	}

	@Override
	public void removeObsever(IAnimateItems obsever) {
		list.remove(obsever);
	}

	@Override
	public void addOptionForBoat(Option option) {
		boat.addOption(option);
	}

	@Override
	public void isMove(boolean x) {
		isThrowed = x;
	}

	@Override
	public void setThread(Thread thread) {
		// TODO Auto-generated method stub
		this.thread = thread;
	}

	@Override
	public Rectangle getBoundingBox() {
		return location.getBounds(width, height);
	}

	@Override
	public void catchedItems(IAnimateItems item) {
		itemCatched = item;
		isCatchOther = true;
		item.updateLocation(location);
	}
	
}
